#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

class String {
public:
    String()
    : _pstr(new char[1]())
    {  cout << "String()" << endl;  }

    String(const char *pstr)
    : _pstr(new char[strlen(pstr) + 1]())
    {
        strcpy(_pstr, pstr);
        cout << "String(const char*)" << endl;
    }

    String(const String &rhs)
    : _pstr(new char[strlen(rhs._pstr) + 1]())
    {
        strcpy(_pstr, rhs._pstr);
        cout << "String(const String &rhs)" << endl;
    }

    ~String() {
        delete[] _pstr;
        _pstr = nullptr;
        cout << "~String()" << endl;
    }

    String &operator = (const String &rhs) {
        if(this != &rhs) {
            delete[] _pstr;
            _pstr = new char[strlen(rhs._pstr) + 1]();
            strcpy(_pstr, rhs._pstr);
        }
        return *this;
    }

    String &operator=(const char *pstr) {
		String rhs(pstr);
		*this = rhs;
		return *this;
#if 0
        if(_pstr) {
            delete[] _pstr;
            _pstr = nullptr;
        }
        _pstr = new char[strlen(pstr) + 1];
        strcpy(_pstr, pstr);
        return *this;
#endif
    }

    String &operator+=(const String &rhs) {
        size_t newSize = strlen(_pstr) + strlen(rhs._pstr) +1;
        char *temp = new char[newSize]();
        strcat(temp, _pstr);
        strcat(temp, rhs._pstr);
        
        if(_pstr) {
            delete[] _pstr;
            _pstr = nullptr;
        }
        _pstr = temp;
        temp = nullptr;
        return *this;
    }

    String &operator+=(const char *pstr) {
		String rhs(pstr);
		*this += rhs;
		return *this;
#if 0
        size_t newSize = strlen(_pstr) + strlen(pstr) + 1;
        char *temp = new char[newSize]();
        strcat(temp, _pstr);
        strcat(temp, pstr);

        if(_pstr) {
            delete[] _pstr;
            _pstr = nullptr;
        }
        _pstr = temp;
        temp = nullptr;
        return *this;
#endif
    }

    char &operator[](std::size_t index) {
        if(index < size()) {
            return _pstr[index];
        } else {
            static char temp = '\0';
            return temp;
        }
    }

    const char &operator[](std::size_t index) const {
        if(index < size()) {
            return _pstr[index];
        } else {
            static char temp = '\0';
            return temp;
        }
    }

    std::size_t size() const {
        return strlen(_pstr);
    }

    const char* c_str() const {
        return _pstr;
    }

    friend bool operator==(const String &str1, const String &str2) {
        return strcmp(str1._pstr, str2._pstr) == 0;
    }

    friend bool operator!=(const String &str1, const String &str2) {
        return strcmp(str1._pstr, str2._pstr) != 0;
    }

    friend bool operator<(const String &str1, const String &str2) {
        return strcmp(str1._pstr, str2._pstr) < 0;
    }

    friend bool operator>(const String &str1, const String &str2) {
        return strcmp(str1._pstr, str2._pstr) > 0;
    }

    friend bool operator<=(const String &str1, const String &str2){
        return strcmp(str1._pstr, str2._pstr) <= 0;
    }

    friend bool operator>=(const String &str1, const String &str2) {
        return strcmp(str1._pstr, str2._pstr) >= 0;
    }

    friend std::ostream &operator<<(std::ostream &os, const String &s) {
        os << s._pstr;
        return os;
    }

    friend std::istream &operator>>(std::istream &is, String &s) {
        if(s._pstr) {
            delete[] s._pstr;
            s._pstr = nullptr;
        }
		
		vector<char> tmp;//缓冲区
		tmp.reserve(1024);

		char ch = '\0';
		while((ch = is.get()), ch !='\n') {
			tmp.push_back(ch);
		}

        s._pstr = new char[tmp.size() + 1]();
        strcpy(s._pstr, &tmp[0]);


#if 0
        char buf[1024] = {0};
        is >> buf;
        s._pstr = new char[strlen(buf) + 1]();
        strcpy(s._pstr, buf);
#endif

        return is;
    }

    void print() {
        if(_pstr) {
            cout << _pstr << endl;
        }
    }

    friend String operator+(const String &, const String &);
    friend String operator+(const String &, const char *);
    friend String operator+(const char *, const String &);

private:
    char *_pstr;
};

String operator+(const String &lhs, const String &rhs) {
    size_t newSize = strlen(lhs._pstr) + strlen(rhs._pstr) + 1;
    char *temp = new char[newSize]();
    strcat(temp, lhs._pstr);
    strcat(temp, rhs._pstr);
    String tempString(temp);

    return tempString;
}

String operator+(const String &lhs, const char *rhs) {
    size_t newSize = strlen(lhs._pstr) + strlen(rhs) + 1;
    char *temp = new char[newSize]();
    strcat(temp, lhs._pstr);
    strcat(temp, rhs);
    String tempString(temp);

    return tempString;
}

String operator+(const char *lhs, const String &rhs) {
    size_t newSize = strlen(lhs) + strlen(rhs._pstr) + 1;
    char *temp = new char[newSize]();
    strcat(temp, lhs);
    strcat(temp, rhs._pstr);
    String tempString(temp);

    return tempString;
}
